/**
 * @FileName: RPCFramework.java
 * @Package: com.ziroom.sms.std.rpc
 * @author liusq23
 * @created 2017/3/10 上午11:19
 * <p>
 * Copyright 2015 ziroom
 */
package com.ziroom.sms.std.rpc;

import com.ziroom.sms.std.proxy.CGlibProxyFactory;
import com.ziroom.sms.std.proxy.ProxyFactory;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

/**
 * <p></p>
 * <p>
 * <PRE>
 * <BR>	修改记录
 * <BR>-----------------------------------------------
 * <BR>	修改日期			修改人			修改内容
 * </PRE>
 *
 * @author liusq23
 * @version 1.0
 * @since 1.0
 */
public class RPCFramework {


    /**
     * 暴露提供者服务
     *
     * @param host
     * @param port
     * @param service
     */
    public static void export(String host, int port, Object service)
            throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException,
            InvocationTargetException {
        if (host == null || host.length() == 0) {
            throw new IllegalArgumentException("host == null");
        }
        if (port < 0 || port > 65535) {
            throw new IllegalArgumentException("port must between 0 to 65535");
        }
        if (service == null) {
            throw new IllegalArgumentException("service is null");
        }
        ServerSocket ssc = new ServerSocket();
        SocketAddress socketAddress = new InetSocketAddress(host, port);
        ssc.bind(socketAddress);
        while (true) {
            Socket socket = ssc.accept();
            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
            String methodName = in.readUTF();
<<<<<<< HEAD
=======
            System.out.println(service.getClass().getName());
>>>>>>> bd63e2b592692e39f1d5d3b87848249c91ebc776
            Class<?>[] parameterTypes = (Class<?>[]) in.readObject();
            Object[] parameters = (Object[]) in.readObject();
            Method method = service.getClass().getMethod(methodName, parameterTypes);
            Object result = method.invoke(service, parameters);
            ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
            out.writeObject(result);
            out.flush();
            socket.close();
        }
    }


    public static <T> T refer(Class<T> interfaceClass, final String host, final int port) throws IOException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
        RpcInvocationHandler rpcInvocationHandler = new RpcInvocationHandler(host, port);
        ProxyFactory proxyFactory = new CGlibProxyFactory();
        return proxyFactory.getProxy(interfaceClass, rpcInvocationHandler);
        //return (T) Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class<?>[]{interfaceClass}, rpcInvocationHandler);
    }

}
